ExposedMembers.AUS = ExposedMembers.AUS or {};
ExposedMembers.AUS.Utils = ExposedMembers.AUS.Utils or {};
AUSUtils = ExposedMembers.AUS.Utils;

local NOTIFICATION_DISCOVER_CONTINENT_HASH = GameInfo.Notifications['NOTIFICATION_DISCOVER_CONTINENT'].Hash
local AUS_PLOT_PROPERTY_FLAG = "PLOT_AUS_UU_BUILT"
local AUS_DISCOVER_NEW_CONTINENT_FLAG = "AUS_DISCOVER_NEW_CONTINENT_"

local AUS_RESOURCE_FLAG = "AUS_RESOURCE_"
local AUS_GOLD_RUSH_FLAG = "AUS_GOLD_RUSH"
local AUS_BREED_IMPORT_FLAG = "AUS_BREED_IMPORT"
local AUS_LONG_RANG_FISHING_FLAG = "AUS_LONG_RANG_FISHING"

local AUS_ALLIANCE_NUM_FLAG = "AUS_ALLIANCE_NUM"
local AUS_IS_AT_WAR_WITH_MAJOR_FLAG = "AUS_IS_AT_WAR_WITH_MAJOR"
local AUS_ALLIANCE_PEACE_FLAG = "AUS_ALLIANCE_PEACE"
local AUS_ALLIANCE_WAR_FLAG = "AUS_ALLIANCE_WAR"

local AUS_ALLIANCE_UNLOCK_UU_FLAG = "AUS_ALLIANCE_UNLOCK_UU_"

local OUTBACK_STATION_COPY_RESOURCE = GlobalParameters.HD_OUTBACK_STATION_COPY_RESOURCE or 0;
local HD_OUTBACK_STATION_IMPORTED_RESOURCE_FLAG = "HD_OUTBACK_STATION_IMPORTED_RESOURCE"

-- 建成区域送对应单位
function AUSOnDistrictConstructed(playerId, districtId, x, y)
  if AUSUtils.CivilizationHasTrait(playerId, 'TRAIT_CIVILIZATION_LAND_DOWN_UNDER') then
    local plot = Map.GetPlot(x, y)
    local city = Cities.GetPlotPurchaseCity(plot);
    -- 矿工
    if AUSUtils.IsDistrictType(districtId, 'DISTRICT_INDUSTRIAL_ZONE') then
      city:AttachModifierByID('GRANT_UNIT_AUS_MINER')
    end
    -- 商业中心
    if AUSUtils.IsDistrictType(districtId, 'DISTRICT_COMMERCIAL_HUB') then
      city:AttachModifierByID('GRANT_UNIT_AUS_HERDER')
    end
    -- 港口
    if AUSUtils.IsDistrictType(districtId, 'DISTRICT_HARBOR') then
      city:AttachModifierByID('GRANT_UNIT_AUS_FISHERMAN')
    end
  end
end
GameEvents.OnDistrictConstructed.Add(AUSOnDistrictConstructed)

-- 发现新大陆送探险家
function AUSDiscoverNewContinent(playerId, notificationId)
  if AUSUtils.CivilizationHasTrait(playerId, 'TRAIT_CIVILIZATION_LAND_DOWN_UNDER') then
    local player = Players[playerId];
    if player:GetProperty('AUS_DISCOVER_NEW_CONTINENT_FLAG' .. notificationId) == 1 then return; end
    local notificationEntry = NotificationManager.Find(playerId, notificationId)
    if notificationEntry and notificationEntry:GetType() == NOTIFICATION_DISCOVER_CONTINENT_HASH then
      player:SetProperty('AUS_DISCOVER_NEW_CONTINENT_FLAG' .. notificationId, 1)
      player:AttachModifierByID('GRANT_UNIT_AUS_EXPLORER');
    end
  end
end
Events.NotificationAdded.Add(AUSDiscoverNewContinent);

-- 改良加产 文化炸弹
function AUSUUBuiltImprovement(playerId, param)
  local x = param.X
  local y = param.Y
  local plot = Map.GetPlot(x, y);
  plot:SetProperty(AUS_PLOT_PROPERTY_FLAG, 1)
end
GameEvents.AUSUUBuiltImprovement.Add(AUSUUBuiltImprovement)

function AUSImprovementRemovedFromMap(x, y, ownerId)
  local plot = Map.GetPlot(x, y);
  plot:SetProperty(AUS_PLOT_PROPERTY_FLAG, 0)
end

-- 淘金热
function AUSGoldRush(playerId, unitId)
  local player = Players[playerId];
	local unit = UnitManager.GetUnit(playerId, unitId);
  local x = unit:GetX()
  local y = unit:GetY()
	local plot = Map.GetPlot(x, y);
  local resourceId = plot:GetResourceType()
  unit:SetProperty(AUS_GOLD_RUSH_FLAG, 1)
  player:SetProperty(AUS_RESOURCE_FLAG .. resourceId, 1)
  Game.AddWorldViewText(playerId, Locale.Lookup("LOC_UNITCOMMAND_GOLD_RUSH_NAME"), x, y)
  
  local cities = player:GetCities();
  if cities ~= nil then
    -- local capital = cities:GetCapitalCity();
    -- if capital then
    --   capital:AttachModifierByID('GRANT_UNIT_AUS_MINER');
    -- end

    for _, city in cities:Members() do
      -- if AUSUtils.CityHasDistrict(city, 'DISTRICT_INDUSTRIAL_ZONE') then
        city:AttachModifierByID('GRANT_UNIT_AUS_MINER')
      -- end
    end
  end

  local movesRemaining = AUSUtils.GetUnitMovesRemaining(playerId, unitId)
  unit:ChangeMovesRemaining(-movesRemaining)

  -- 改名
  local name = Locale.Lookup(unit:GetName())
  name = name .. ' [ICON_' .. GameInfo.Resources[resourceId].ResourceType .. ']'
  unit:GetExperience():SetVeteranName(name)
end
GameEvents.AUSGoldRush.Add(AUSGoldRush)

-- 畜种引进
function AUSBreedImport(playerId, unitId)
  local player = Players[playerId];
	local unit = UnitManager.GetUnit(playerId, unitId);
  local x = unit:GetX()
  local y = unit:GetY()
	local plot = Map.GetPlot(x, y);
  local resourceId = plot:GetResourceType()
  unit:SetProperty(AUS_BREED_IMPORT_FLAG, 1)
  player:SetProperty(AUS_RESOURCE_FLAG .. resourceId, 1)
  Game.AddWorldViewText(playerId, Locale.Lookup("LOC_UNITCOMMAND_BREED_IMPORT_NAME"), x, y)

  local cities = player:GetCities();
  if cities ~= nil then
    -- local capital = cities:GetCapitalCity();
    -- if capital then
    --   capital:AttachModifierByID('GRANT_UNIT_AUS_HERDER');
    -- end

    for _, city in cities:Members() do
      -- if AUSUtils.CityHasDistrict(city, 'DISTRICT_COMMERCIAL_HUB') then
        city:AttachModifierByID('GRANT_UNIT_AUS_HERDER');
      -- end
    end
  end

  local movesRemaining = AUSUtils.GetUnitMovesRemaining(playerId, unitId)
  unit:ChangeMovesRemaining(-movesRemaining)

  -- 和而不同内陆牧场适配
  if OUTBACK_STATION_COPY_RESOURCE == 1 then
    local resourceType = GameInfo.Resources[resourceId].ResourceType;
    for row in GameInfo.Improvement_ValidResources() do
      if row.ResourceType == resourceType and row.ImprovementType == 'IMPROVEMENT_PASTURE' then
        print("畜种引进 和而不同内陆牧场适配", resourceType)
        local resourceList = player:GetProperty(HD_OUTBACK_STATION_IMPORTED_RESOURCE_FLAG) or {};
        table.insert(resourceList, resourceId);
        player:SetProperty(HD_OUTBACK_STATION_IMPORTED_RESOURCE_FLAG, resourceList)
        break;
      end
    end
  end

  -- 改名
  local name = Locale.Lookup(unit:GetName())
  name = name .. ' [ICON_' .. GameInfo.Resources[resourceId].ResourceType .. ']'
  unit:GetExperience():SetVeteranName(name)
end
GameEvents.AUSBreedImport.Add(AUSBreedImport)

-- 远洋捕捞
function AUSLongRangFishing(playerId, unitId)
  local player = Players[playerId];
	local unit = UnitManager.GetUnit(playerId, unitId);
  local x = unit:GetX()
  local y = unit:GetY()
	local plot = Map.GetPlot(x, y);
  local resourceId = plot:GetResourceType()
  unit:SetProperty(AUS_LONG_RANG_FISHING_FLAG, 1)
  player:SetProperty(AUS_RESOURCE_FLAG .. resourceId, 1)
  Game.AddWorldViewText(playerId, Locale.Lookup("LOC_UNITCOMMAND_LONG_RANG_FISHING_NAME"), x, y)
  
  local cities = player:GetCities();
  if cities ~= nil then
    -- local capital = cities:GetCapitalCity();
    -- if capital then
    --   capital:AttachModifierByID('GRANT_UNIT_AUS_FISHERMAN');
    -- end

    for _, city in cities:Members() do
      -- if AUSUtils.CityHasDistrict(city, 'DISTRICT_HARBOR') then
        city:AttachModifierByID('GRANT_UNIT_AUS_FISHERMAN')
      -- end
    end
  end

  local movesRemaining = AUSUtils.GetUnitMovesRemaining(playerId, unitId)
  unit:ChangeMovesRemaining(-movesRemaining)

  -- 改名
  local name = Locale.Lookup(unit:GetName())
  name = name .. ' [ICON_' .. GameInfo.Resources[resourceId].ResourceType .. ']'
  unit:GetExperience():SetVeteranName(name)
end
GameEvents.AUSLongRangFishing.Add(AUSLongRangFishing)

-- 同盟送政策槽位
function AUSAlliancesAddSlot(playerId)
  AUSRefreshAlliance(playerId)
end
GameEvents.PlayerTurnStartComplete.Add(AUSAlliancesAddSlot)

function AUSAlliance(playerId, alliesId)
  AUSRefreshAlliance(playerId)
  AUSUnlockUU(playerId, alliesId)
end
Events.DiplomacyRelationshipChanged.Add(AUSAlliance)

function AUSRefreshAlliance(playerId)
  if AUSUtils.LeaderHasTrait(playerId, 'TRAIT_LEADER_CITADEL_CIVILIZATION') then
    local player = Players[playerId]
    local allianceNum = 0
    local alivePlayers = PlayerManager.GetAliveMajorIDs()
    for _, alivePlayerId in ipairs(alivePlayers) do
      if playerId ~= alivePlayerId then
        local allianceType = AUSUtils.GetAllianceType(playerId, alivePlayerId)
        if allianceType ~= nil and allianceType ~= -1 then
          allianceNum = allianceNum + 1
          local peaceNum = player:GetProperty(AUS_ALLIANCE_PEACE_FLAG) or 0
          local warNum = player:GetProperty(AUS_ALLIANCE_WAR_FLAG) or 0

          local allianceLevel = AUSUtils.GetAllianceLevel(playerId, alivePlayerId)
          local allies = Players[alivePlayerId]
          local isAtWar = allies:GetProperty(AUS_IS_AT_WAR_WITH_MAJOR_FLAG) or 0
          if isAtWar > 0 then
            if allianceLevel > warNum then
              player:SetProperty(AUS_ALLIANCE_WAR_FLAG, allianceLevel)
              for i=1,allianceLevel-warNum,1 do
                print("AUSAlliance 增加军事槽位")
                player:AttachModifierByID('AUS_MILITARY_GOVERNMENT_SLOT')
              end
            end
          else
            if allianceLevel > peaceNum then
              player:SetProperty(AUS_ALLIANCE_PEACE_FLAG, allianceLevel)
              for i=1,allianceLevel-peaceNum,1 do
                print("AUSAlliance 增加经济槽位")
                player:AttachModifierByID('AUS_ECONOMIC_GOVERNMENT_SLOT')
              end
            end
          end

          print("AUSAlliance 有效同盟个数", allianceNum)
          player:SetProperty(AUS_ALLIANCE_NUM_FLAG, allianceNum)
          local cities = player:GetCities();
          if cities ~= nil then
            for _, city in cities:Members() do
              local cityPlot = Map.GetPlot(city:GetX(), city:GetY())
              cityPlot:SetProperty(AUS_ALLIANCE_NUM_FLAG, allianceNum)
            end
          end
        end
      end
    end
  end
end

function AUSUnlockUU(playerId, alliesId)
  local allianceType = AUSUtils.GetAllianceType(playerId, alliesId)
  if allianceType == nil or allianceType == -1 then
    return;
  end
  if AUSUtils.LeaderHasTrait(playerId, 'TRAIT_LEADER_CITADEL_CIVILIZATION') then
    local player = Players[playerId]
    local alliesConfig = PlayerConfigurations[alliesId]
	  local civType = alliesConfig:GetCivilizationTypeName()
    local leaderType = alliesConfig:GetLeaderTypeName()
    local traitTypeList = {}
    if player:GetProperty(AUS_ALLIANCE_UNLOCK_UU_FLAG .. civType) ~= 1 then
      player:SetProperty(AUS_ALLIANCE_UNLOCK_UU_FLAG .. civType, 1)
      for row in GameInfo.CivilizationTraits() do
        if row.CivilizationType == civType then
          table.insert(traitTypeList, row.TraitType)
        end
      end
    end
    
    if player:GetProperty(AUS_ALLIANCE_UNLOCK_UU_FLAG .. leaderType) ~= 1 then
      player:SetProperty(AUS_ALLIANCE_UNLOCK_UU_FLAG .. leaderType, 1)
      for row in GameInfo.LeaderTraits() do
        if row.LeaderType == leaderType then
          table.insert(traitTypeList, row.TraitType)
        end
      end
    end

    if #traitTypeList == 0 then
      return;
    end
    for row in GameInfo.Units() do
      if row.TraitType ~= nil and row.CanTrain == true then
        for _, traitType in ipairs(traitTypeList) do
          if row.TraitType == traitType then
            player:AttachModifierByID('AUS_ALLIANCE_UNLOCK_' .. row.UnitType)
            print("AUSAlliance 解锁盟友特色单位", 'AUS_ALLIANCE_UNLOCK_' .. row.UnitType)
          end
        end
      end
    end
  end
end

function AUSCityAddedToMap(playerId, cityId, x, y)
  local player = Players[playerId]
  local allianceNum = player:GetProperty(AUS_ALLIANCE_NUM_FLAG) or 0
  local cityPlot = Map.GetPlot(x, y)
  cityPlot:SetProperty(AUS_ALLIANCE_NUM_FLAG, allianceNum)
end

function AUSCityConquered(newPlayerId, oldPlayerId, newCityId, x, y)
  local player = Players[newPlayerId]
  local allianceNum = player:GetProperty(AUS_ALLIANCE_NUM_FLAG) or 0
  local cityPlot = Map.GetPlot(x, y)
  cityPlot:SetProperty(AUS_ALLIANCE_NUM_FLAG, allianceNum)
end
GameEvents.CityConquered.Add(AUSCityConquered)
--------------------------------------------------------------
-- Initialize
function initialize()
	Events.ImprovementRemovedFromMap.Add(AUSImprovementRemovedFromMap);
  Events.CityAddedToMap.Add(AUSCityAddedToMap);
end
Events.LoadGameViewStateDone.Add(initialize);